/*
 * Copyright 2020-2030 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

package com.gitee.minimalismstyle.fresh.flowable.api.feign

import org.springframework.web.bind.annotation.*
import com.gitee.minimalismstyle.fresh.common.core.domain.R
import com.gitee.minimalismstyle.fresh.flowable.api.annotation.FlowableClient
import com.gitee.minimalismstyle.fresh.flowable.api.config.FlowableFeignConfig
import com.gitee.minimalismstyle.fresh.flowable.api.feign.model.*
import java.io.File

/**
 * Executions
 * @author maoxiaodong
 */
@FlowableClient(configuration = [FlowableFeignConfig::class])
interface ExecutionsApi {


    /**
     * The request body can contain all possible filters that can be used in the List executions URL query. On top of these, it’s possible to provide an array of variables and processInstanceVariables to include in the query, with their format described here.

    The general paging and sorting query-parameters can be used for this URL.
     */
    @PostMapping("/query/executions")
    fun queryExecutions(
        @RequestBody(required = false) body: ExecutionQueryRequest?
    ): R<DataResponse<ExecutionResponse>>

    /**
     * List of executions
     */
    @GetMapping("/runtime/executions")
    fun listExecutions(
        @RequestParam(name = "id", required = false) id: String?,
        @RequestParam(name = "activityId", required = false) activityId: String?,
        @RequestParam(name = "processDefinitionKey", required = false) processDefinitionKey: String?,
        @RequestParam(name = "processDefinitionId", required = false) processDefinitionId: String?,
        @RequestParam(name = "processInstanceId", required = false) processInstanceId: String?,
        @RequestParam(name = "messageEventSubscriptionName", required = false) messageEventSubscriptionName: String?,
        @RequestParam(name = "signalEventSubscriptionName", required = false) signalEventSubscriptionName: String?,
        @RequestParam(name = "parentId", required = false) parentId: String?,
        @RequestParam(name = "tenantId", required = false) tenantId: String?,
        @RequestParam(name = "tenantIdLike", required = false) tenantIdLike: String?,
        @RequestParam(name = "withoutTenantId", required = false) withoutTenantId: Boolean?,
        @RequestParam(name = "sort", required = false) sort: String?
    ): R<DataResponse<ExecutionResponse>>

    /**
     * Signal event received
     */
    @PutMapping("/runtime/executions")
    fun executeExecutionAction(
        @RequestBody(required = false) body: ExecutionActionRequest?
    ): R<Any>

    /**
     * Get an execution
     */
    @GetMapping("/runtime/executions/{executionId}")
    fun getExecution(
        @PathVariable("executionId") executionId: String
    ): R<ExecutionResponse>

    /**
     * Execute an action on an execution
     */
    @PutMapping("/runtime/executions/{executionId}")
    fun performExecutionAction(
        @PathVariable("executionId") executionId: String,
        @RequestBody(required = false) body: ExecutionActionRequest?
    ): R<ExecutionResponse>

    /**
     * Returns all activities which are active in the execution and in all child-executions (and their children, recursively), if any.
     */
    @GetMapping("/runtime/executions/{executionId}/activities")
    fun listExecutionActiveActivities(
        @PathVariable("executionId") executionId: String
    ): R<Any>

    /**
     * Change the state of an execution
     */
    @PostMapping("/runtime/executions/{executionId}/change-state")
    fun changeExecutionActivityState(
        @PathVariable("executionId") executionId: String,
        @RequestBody(required = false) body: ExecutionChangeActivityStateRequest?
    ): R<Any>

    /**
     * List variables for an execution
     */
    @GetMapping("/runtime/executions/{executionId}/variables")
    fun listExecutionVariables(
        @PathVariable("executionId") executionId: String,
        @RequestParam(name = "scope", required = false) scope: String?
    ): R<Any>

    /**
     * This endpoint can be used in 2 ways: By passing a JSON Body (array of RestVariable) or by passing a multipart/form-data Object.
    Any number of variables can be passed into the request body array.
    NB: Swagger V2 specification does not support this use case that is why this endpoint might be buggy/incomplete if used with other tools.
     */
    @PostMapping("/runtime/executions/{executionId}/variables")
    fun createExecutionVariable(
        @PathVariable("executionId") executionId: String,
        @RequestBody(required = false) body: ExecutionVariableCollectionResource?,
        @RequestParam(name = "name", required = false) name: String?,
        @RequestParam(name = "type", required = false) type: String?,
        @RequestParam(name = "scope", required = false) scope: String?
    ): R<Any>

    /**
     * This endpoint can be used in 2 ways: By passing a JSON Body (array of RestVariable) or by passing a multipart/form-data Object.
    Any number of variables can be passed into the request body array.
    NB: Swagger V2 specification does not support this use case that is why this endpoint might be buggy/incomplete if used with other tools.
     */
    @PutMapping("/runtime/executions/{executionId}/variables")
    fun createOrUpdateExecutionVariable(
        @PathVariable("executionId") executionId: String,
        @RequestBody(required = false) body: ExecutionVariableCollectionResource?,
        @RequestParam(name = "name", required = false) name: String?,
        @RequestParam(name = "type", required = false) type: String?,
        @RequestParam(name = "scope", required = false) scope: String?
    ): R<Any>

    /**
     * Delete all variables for an execution
     */
    @DeleteMapping("/runtime/executions/{executionId}/variables")
    fun deleteLocalVariables(
        @PathVariable("executionId") executionId: String
    ): R<Any>

    /**
     * Get a variable for an execution
     */
    @GetMapping("/runtime/executions/{executionId}/variables/{variableName}")
    fun getExecutionVariable(
        @PathVariable("executionId") executionId: String,
        @PathVariable("variableName") variableName: String,
        @RequestParam(name = "scope", required = false) scope: String?
    ): R<RestVariable>

    /**
     * This endpoint can be used in 2 ways: By passing a JSON Body (RestVariable) or by passing a multipart/form-data Object.
    NB: Swagger V2 specification does not support this use case that is why this endpoint might be buggy/incomplete if used with other tools.
     */
    @PutMapping("/runtime/executions/{executionId}/variables/{variableName}")
    fun updateExecutionVariable(
        @PathVariable("executionId") executionId: String,
        @PathVariable("variableName") variableName: String,
        @RequestBody(required = false) body: ExecutionVariableResource?,
        @RequestParam(name = "file", required = false) file: File?,
        @RequestParam(name = "name", required = false) name: String?,
        @RequestParam(name = "type", required = false) type: String?,
        @RequestParam(name = "scope", required = false) scope: String?
    ): R<RestVariable>

    /**
     * Delete a variable for an execution
     */
    @DeleteMapping("/runtime/executions/{executionId}/variables/{variableName}")
    fun deletedExecutionVariable(
        @PathVariable("executionId") executionId: String,
        @PathVariable("variableName") variableName: String,
        @RequestParam(name = "scope", required = false) scope: String?
    ): R<Any>

    /**
     * Get the binary data for an execution
     */
    @GetMapping("/runtime/executions/{executionId}/variables/{variableName}/data")
    fun getExecutionVariableData(
        @PathVariable("executionId") executionId: String,
        @PathVariable("variableName") variableName: String,
        @RequestParam(name = "scope", required = false) scope: String?
    ): R<Any>
}